/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.emex.app.stuff.gui;

import com.emex.app.shared.data.Car;
import com.emex.app.shared.data.Client;
import com.emex.app.shared.data.JuridicalPerson;
import com.emex.app.shared.data.Numbers;
import com.emex.app.shared.data.OrderPayment;
import com.emex.app.shared.data.OrderPosition;
import com.emex.app.shared.data.Orders;
import com.emex.app.shared.data.Position;
import com.emex.app.shared.data.User;
import com.emex.app.shared.data.enums.OrderStatus;
import com.emex.app.shared.data.enums.PayMethod;
import com.emex.app.stuff.constant.ReportName;
import com.emex.app.stuff.gui.model.OrderPaymentTableModel;
import com.emex.app.stuff.gui.model.OrderPositionTableModel;
import com.emex.app.stuff.gui.model.OrdersTableModel;
import com.emex.app.stuff.provider.AuthenticationDataProvider;
import com.emex.app.stuff.provider.CompanyInfoDataProvider;
import com.emex.app.stuff.provider.JuridicalPersonDataProvider;
import com.emex.app.stuff.provider.OrderDataProvider;
import com.emex.app.stuff.provider.ShopDataProvider;
import com.emex.app.stuff.security.SecurityManager;
import com.emex.app.stuff.utils.AdminUtils;
import com.emex.app.stuff.utils.DateUtils;
import com.emex.app.stuff.utils.MoneyToString;
import com.emex.app.stuff.utils.ReportGenerator;
import com.emex.app.stuff.utils.StringUtilities;
import com.emex.app.stuff.utils.UIUtils;
import java.awt.Frame;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComponent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRMapArrayDataSource;
import org.openide.windows.WindowManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Sergey Karavaev
 */
public class OrderDialog extends javax.swing.JDialog {

    private static Logger logger = LoggerFactory.getLogger(OrderDialog.class);

    private static Frame mainWindow = WindowManager.getDefault().getMainWindow();

    private Orders order;

    private Client client;

    private JuridicalPerson juridicalPerson;

    private List<OrderPosition> orderPositions;

    private List<OrderPayment> orderPayments;

    private OrderPositionTableModel orderPositionTableModel;

    private OrderPaymentTableModel orderPaymentTableModel;

    private OrdersTableModel ordersTableModel;

    private Car car;

    /**
     * Creates new form AddNewOrder
     */
    public OrderDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        statusComboBox.setModel(new DefaultComboBoxModel(OrderStatus.values()));
        orderDatePicker.setFormats(DateUtils.getSimpleDateFormat());
        orderDatePicker.setDate(new Date());
        if (!SecurityManager.getDefault().getCurrentPerson().getIsAdmin()) {
            List<JComponent> components = new ArrayList<>();
            components.add(deleteOrderPosition);
            components.add(deletePaymentButton);
            components.add(editPaymentButton);
            AdminUtils.hideControls(components);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        saveButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        orderPositionsPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        orderPositionsTable = new org.jdesktop.swingx.JXTable();
        addOrderPosition = new javax.swing.JButton();
        editViewButton = new javax.swing.JButton();
        deleteOrderPosition = new javax.swing.JButton();
        addFromShopButton = new javax.swing.JButton();
        printSchetButton = new javax.swing.JButton();
        orderDetailsPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        orderDatePicker = new org.jdesktop.swingx.JXDatePicker();
        jLabel3 = new javax.swing.JLabel();
        statusComboBox = new javax.swing.JComboBox();
        paymentsPanel = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        paymentsTable = new org.jdesktop.swingx.JXTable();
        addPaymentButton = new javax.swing.JButton();
        editPaymentButton = new javax.swing.JButton();
        deletePaymentButton = new javax.swing.JButton();
        printPrePaymentsButton = new javax.swing.JButton();
        moneyPanel = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        generalSumField = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        ostTextField = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.title")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(saveButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.saveButton.text")); // NOI18N
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.cancelButton.text")); // NOI18N
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        orderPositionsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.orderPositionsPanel.border.title"))); // NOI18N

        orderPositionsTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                orderPositionsTableMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(orderPositionsTable);

        org.openide.awt.Mnemonics.setLocalizedText(addOrderPosition, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.addOrderPosition.text")); // NOI18N
        addOrderPosition.setActionCommand(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.addOrderPosition.actionCommand")); // NOI18N
        addOrderPosition.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addOrderPositionActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(editViewButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.editViewButton.text")); // NOI18N
        editViewButton.setEnabled(false);
        editViewButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editViewButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(deleteOrderPosition, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.deleteOrderPosition.text")); // NOI18N
        deleteOrderPosition.setEnabled(false);
        deleteOrderPosition.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteOrderPositionActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(addFromShopButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.addFromShopButton.text")); // NOI18N
        addFromShopButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addFromShopButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(printSchetButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.printSchetButton.text")); // NOI18N
        printSchetButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                printSchetButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout orderPositionsPanelLayout = new javax.swing.GroupLayout(orderPositionsPanel);
        orderPositionsPanel.setLayout(orderPositionsPanelLayout);
        orderPositionsPanelLayout.setHorizontalGroup(
            orderPositionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(orderPositionsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(orderPositionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(orderPositionsPanelLayout.createSequentialGroup()
                        .addComponent(addOrderPosition)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(addFromShopButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(editViewButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(deleteOrderPosition)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(printSchetButton)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        orderPositionsPanelLayout.setVerticalGroup(
            orderPositionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(orderPositionsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 97, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(orderPositionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addOrderPosition)
                    .addComponent(editViewButton)
                    .addComponent(deleteOrderPosition)
                    .addComponent(addFromShopButton)
                    .addComponent(printSchetButton))
                .addContainerGap())
        );

        orderDetailsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.orderDetailsPanel.border.title"))); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.jLabel1.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.jLabel3.text")); // NOI18N

        javax.swing.GroupLayout orderDetailsPanelLayout = new javax.swing.GroupLayout(orderDetailsPanel);
        orderDetailsPanel.setLayout(orderDetailsPanelLayout);
        orderDetailsPanelLayout.setHorizontalGroup(
            orderDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(orderDetailsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(orderDatePicker, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addComponent(jLabel3)
                .addGap(18, 18, 18)
                .addComponent(statusComboBox, 0, 308, Short.MAX_VALUE)
                .addContainerGap())
        );
        orderDetailsPanelLayout.setVerticalGroup(
            orderDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(orderDetailsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(orderDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(orderDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3)
                    .addComponent(statusComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        paymentsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.paymentsPanel.border.title"))); // NOI18N

        paymentsTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                paymentsTableMouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(paymentsTable);

        org.openide.awt.Mnemonics.setLocalizedText(addPaymentButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.addPaymentButton.text")); // NOI18N
        addPaymentButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addPaymentButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(editPaymentButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.editPaymentButton.text")); // NOI18N
        editPaymentButton.setEnabled(false);
        editPaymentButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editPaymentButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(deletePaymentButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.deletePaymentButton.text")); // NOI18N
        deletePaymentButton.setEnabled(false);
        deletePaymentButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deletePaymentButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(printPrePaymentsButton, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.printPrePaymentsButton.text")); // NOI18N
        printPrePaymentsButton.setEnabled(false);
        printPrePaymentsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                printPrePaymentsButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout paymentsPanelLayout = new javax.swing.GroupLayout(paymentsPanel);
        paymentsPanel.setLayout(paymentsPanelLayout);
        paymentsPanelLayout.setHorizontalGroup(
            paymentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(paymentsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(paymentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2)
                    .addGroup(paymentsPanelLayout.createSequentialGroup()
                        .addComponent(addPaymentButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(editPaymentButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(deletePaymentButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(printPrePaymentsButton)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        paymentsPanelLayout.setVerticalGroup(
            paymentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(paymentsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(paymentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addPaymentButton)
                    .addComponent(editPaymentButton)
                    .addComponent(deletePaymentButton)
                    .addComponent(printPrePaymentsButton))
                .addContainerGap())
        );

        moneyPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.moneyPanel.border.title"))); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.jLabel4.text")); // NOI18N
        jLabel4.setToolTipText(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.jLabel4.toolTipText")); // NOI18N

        generalSumField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        generalSumField.setText(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.generalSumField.text")); // NOI18N
        generalSumField.setEnabled(false);

        org.openide.awt.Mnemonics.setLocalizedText(jLabel5, org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.jLabel5.text")); // NOI18N

        ostTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        ostTextField.setText(org.openide.util.NbBundle.getMessage(OrderDialog.class, "OrderDialog.ostTextField.text")); // NOI18N
        ostTextField.setEnabled(false);

        javax.swing.GroupLayout moneyPanelLayout = new javax.swing.GroupLayout(moneyPanel);
        moneyPanel.setLayout(moneyPanelLayout);
        moneyPanelLayout.setHorizontalGroup(
            moneyPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(moneyPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel4)
                .addGap(18, 18, 18)
                .addComponent(generalSumField, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jLabel5)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(ostTextField)
                .addContainerGap())
        );
        moneyPanelLayout.setVerticalGroup(
            moneyPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(moneyPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(moneyPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(generalSumField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5)
                    .addComponent(ostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(orderPositionsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(orderDetailsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(paymentsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(saveButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelButton))
                    .addComponent(moneyPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(orderPositionsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(orderDetailsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(paymentsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(moneyPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(saveButton)
                    .addComponent(cancelButton))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        this.setVisible(false);
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void addOrderPositionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addOrderPositionActionPerformed
        OrderPositionDialog dialog = new OrderPositionDialog(mainWindow, rootPaneCheckingEnabled);
        dialog.setTableModelToUpdate(orderPositionTableModel);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
        calculateGeneralSum();
    }//GEN-LAST:event_addOrderPositionActionPerformed

    private void editViewButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editViewButtonActionPerformed
        OrderPositionDialog dialog = new OrderPositionDialog(mainWindow, rootPaneCheckingEnabled);
        dialog.setOrderPosition(getOrderPositionSelection());
        dialog.setTableModelToUpdate(orderPositionTableModel);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
        calculateGeneralSum();
    }//GEN-LAST:event_editViewButtonActionPerformed

    private void deleteOrderPositionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteOrderPositionActionPerformed
        OrderPosition toRemove = getOrderPositionSelection();
        orderPositionTableModel.dataRemoved(toRemove);
        if (null != toRemove.getId()) {
            OrderDataProvider.getInstance().deleteOrderPositionByPrimaryKey(toRemove.getId());
        }
        calculateGeneralSum();
    }//GEN-LAST:event_deleteOrderPositionActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        // 1. Save Orders
        boolean operationCreate = false;

        if (order == null) {
            order = new Orders();
            operationCreate = true;
        }
        if (orderDatePicker.getDate() == null) {
            UIUtils.showErrorMessage("Заполните дату заказа");
            return;
        }
        if (null == statusComboBox.getSelectedItem()) {
            UIUtils.showErrorMessage("Укажите статус заказа");
            return;
        }

        order.setDate(orderDatePicker.getDate());
        OrderStatus orderStatus = (OrderStatus) statusComboBox.getItemAt(statusComboBox.getSelectedIndex());
        order.setStatus(orderStatus.ordinal());

        if (operationCreate) {
            order.setManagerId(SecurityManager.getDefault().getCurrentPerson().getId());
            order.setName("Заказ от " + DateUtils.getExtendedFormattedString(orderDatePicker.getDate()));
            if (null != client) {
                order.setClientId(client.getId());
            } else if (null != juridicalPerson) {
                order.setJurClienId(juridicalPerson.getId());
            }
            if (null != car) {
                order.setCarId(car.getId());
            } else {
                // Dummy
                order.setCarId(1);
            }

            order = OrderDataProvider.getInstance().insertOrder(order);
            ordersTableModel.dataAdded(order);
        } else {
            OrderDataProvider.getInstance().updateOrderByPrimaryKey(order);
            ordersTableModel.dataUpdated();
        }

        // 2. Save order positions
        for (OrderPosition op : orderPositions) {
            if (op.getId() == null) {
                // Newly added record
                op.setOrderId(order.getId());
                OrderDataProvider.getInstance().insertOrderPosition(op);
            } else {
                // Update record
                OrderDataProvider.getInstance().updateOrderPositionByPrimaryKey(op);
            }

            // Check if it from shop - need to reduce count
            if (null != op.getPosition()) {
                Position toSell = op.getPosition();
                toSell.setAmount(toSell.getAmount() - op.getAmount());
                ShopDataProvider.getInstance().updatePosition(toSell);
            }
        }

        // 3. Save order payments
        for (OrderPayment op : orderPayments) {
            if (op.getId() == null) {
                // Newly added record
                op.setOrderId(order.getId());
                OrderDataProvider.getInstance().insertOrderPayment(op);
            } else {
                // Update record
                OrderDataProvider.getInstance().updateOrderPaymentByPrimaryKey(op);
            }
        }

        this.setVisible(false);
    }//GEN-LAST:event_saveButtonActionPerformed

    private void addPaymentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addPaymentButtonActionPerformed
        OrderPaymentDialog dialog = new OrderPaymentDialog(mainWindow, true);
        dialog.setTableModelToUpdate(orderPaymentTableModel);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
        calculateGeneralSum();
        checkPrePaymentPrintAvailability();
    }//GEN-LAST:event_addPaymentButtonActionPerformed

    private void editPaymentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editPaymentButtonActionPerformed
        OrderPaymentDialog dialog = new OrderPaymentDialog(mainWindow, true);
        dialog.setOrderPayment(getOrderPaymentSelection());
        dialog.setTableModelToUpdate(orderPaymentTableModel);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
        calculateGeneralSum();
        checkPrePaymentPrintAvailability();
    }//GEN-LAST:event_editPaymentButtonActionPerformed

    private void deletePaymentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deletePaymentButtonActionPerformed
        OrderPayment toRemove = getOrderPaymentSelection();
        orderPaymentTableModel.dataRemoved(toRemove);
        if (null != toRemove.getId()) {
            OrderDataProvider.getInstance().deleteOrderPaymentByPrimaryKey(toRemove.getId());
        }
        calculateGeneralSum();
        checkPrePaymentPrintAvailability();
    }//GEN-LAST:event_deletePaymentButtonActionPerformed

    private void printPrePaymentsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_printPrePaymentsButtonActionPerformed
        if (null != order && orderPayments != null && !orderPayments.isEmpty()) {
            try {
                HashMap parameters = new HashMap();

                BufferedImage image = ImageIO.read(getClass().getClassLoader().getResource("emexLogo.jpg"));
                parameters.put("logo", image);
                parameters.put("orderName", order.getName());
                Double genSumma = 0.0;

                parameters.put("currentDate", DateUtils.getFormatedDateString(new Date()));
                User manager = SecurityManager.getDefault().getCurrentPerson();
                StringBuilder fio = new StringBuilder();
                fio.append(manager.getSurname()).append(" ").append(manager.getName())
                        .append(" ").append(manager.getPatronymic());
                parameters.put("manager", fio.toString());

                List<Map<String, String>> tableData = new ArrayList<>();
                for (OrderPayment op : orderPayments) {
                    Map<String, String> ordPayInfo = new HashMap<>();
                    genSumma += op.getSumma();
                    ordPayInfo.put("name", op.getName());
                    ordPayInfo.put("payMethod", PayMethod.valueOf(op.getPayMethod()).toString());
                    ordPayInfo.put("summa", op.getSumma().toString());
                    User man = AuthenticationDataProvider.getInstance().selectUserByPrimaryKey(op.getManagerId());
                    String managerFio = "";
                    if (null != man) {
                        managerFio = StringUtilities.getManagerFIO(man);
                    }
                    ordPayInfo.put("manager", managerFio);
                    tableData.add(ordPayInfo);
                }
                parameters.put("genSumma", genSumma.toString());
                Map<String, String>[] tableDS = tableData.toArray(new HashMap[tableData.size()]);
                JRMapArrayDataSource mapDS = new JRMapArrayDataSource(tableDS);
                parameters.put("datasource", new JREmptyDataSource());
                parameters.put("dataSource", mapDS);
                JasperPrint jp = ReportGenerator.getInstance().generateReport(parameters, ReportName.PRE_PAYMENT_REPORT);
                ReportGenerator.getInstance().showReport(jp);
            } catch (Exception ex) {
                ex.printStackTrace();
                UIUtils.showErrorMessage("Произошли ошибки при печати отчета по оплатам");
            }
        }
    }//GEN-LAST:event_printPrePaymentsButtonActionPerformed

    private void orderPositionsTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_orderPositionsTableMouseClicked
        if (evt.getClickCount() == 2) {
            editViewButtonActionPerformed(null);
        }
    }//GEN-LAST:event_orderPositionsTableMouseClicked

    private void paymentsTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_paymentsTableMouseClicked
        if (evt.getClickCount() == 2) {
            editPaymentButtonActionPerformed(null);
        }
    }//GEN-LAST:event_paymentsTableMouseClicked

    private void addFromShopButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addFromShopButtonActionPerformed
        SearchPositionDialog dialog = new SearchPositionDialog(mainWindow, true);
        dialog.setLocationRelativeTo(null);
        dialog.setOrderPositionTableModel(orderPositionTableModel);
        dialog.setVisible(true);
        calculateGeneralSum();
    }//GEN-LAST:event_addFromShopButtonActionPerformed

    private void printSchetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_printSchetButtonActionPerformed
        if (juridicalPerson == null) {
            UIUtils.showInfoMessage("Выставление счетов возможно только для юридических клиентов");
            return;
        }
        if (null != orderPositions && !orderPositions.isEmpty()) {
            Numbers numbers = CompanyInfoDataProvider.getInstance().getNumbers();
            Long numSchet = numbers.getSchetNum();
            numSchet++;
            numbers.setSchetNum(numSchet);
            CompanyInfoDataProvider.getInstance().updateNumbers(numbers);
            Map<String, Object> params = new HashMap<>();
            JuridicalPerson seller = JuridicalPersonDataProvider.getInstance().selectJuridicalPersonByPrimaryKey(
                    CompanyInfoDataProvider.getInstance().getCompanyInfo().getJurPersonId());
            params.put("title", "СЧЕТ № " + numSchet + " от " + DateUtils.getFormatedDateString(new Date()));
            params.put("seller", StringUtilities.getAddressantForSchet(seller)
                    + StringUtilities.getAddressantForSchet(juridicalPerson).replaceFirst("Продавец", "Покупатель"));
            List<Map<String, String>> tableData = new ArrayList<>();
            Double genSumma = 0.0;
            Integer genAmount = 0;
            Integer posNum = 1;
            for (OrderPosition op : orderPositions) {
                Map<String, String> item = new HashMap<>();
                genAmount += op.getAmount();
                genSumma += (op.getAmount() * op.getPrice());
                item.put("field1", posNum.toString());
                item.put("field2", op.getName());
                item.put("field3", "1");
                item.put("field4", op.getAmount().toString());
                item.put("field5", op.getPrice().toString().endsWith(".0") ? op.getPrice().toString() + "0" : op.getPrice().toString());
                Double sum = op.getAmount() * op.getPrice();
                item.put("field6", sum.toString().endsWith(".0") ? sum.toString() + "0" : sum.toString());
                tableData.add(item);
                ++posNum;
            }
            params.put("genAmount", genAmount.toString());
            params.put("genSumma", genSumma.toString().endsWith(".0") ? genSumma.toString() + "0" : genSumma.toString());
            params.put("sumInWords", "Cумма прописью: " + new MoneyToString().convert(genSumma));
            params.put("recordOne", "Руководитель предприятия________________________");
            params.put("recordTwo", "Бухгалтер_________________________");
            Map<String, String>[] tableDS = tableData.toArray(new HashMap[tableData.size()]);
            JRMapArrayDataSource mapDS = new JRMapArrayDataSource(tableDS);
            params.put("datasource", new JREmptyDataSource());
            params.put("positionsDataSource", mapDS);
            try {
                JasperPrint schet = ReportGenerator.getInstance().generateReport(params, ReportName.SCHET);
                ReportGenerator.getInstance().showReport(schet);
            } catch (JRException ex) {
                ex.printStackTrace();
                UIUtils.showErrorMessage("Произошли ошибки при печати счета");
            }
        }

    }//GEN-LAST:event_printSchetButtonActionPerformed

    public void setClient(Client client) {
        this.client = client;
    }

    public void setOrder(Orders order) {
        this.order = order;
        if (null == order) {
            orderPayments = new ArrayList<>();
            orderPositions = new ArrayList<>();
        } else {
            orderPayments = OrderDataProvider.getInstance().getOrderPaymentByOrderId(order.getId());
            orderPositions = OrderDataProvider.getInstance().getOrderPositionByOrderId(order.getId());
            orderDatePicker.setDate(order.getDate());
            statusComboBox.setSelectedItem(OrderStatus.valueOf(order.getStatus()));
        }

        orderPositionTableModel = new OrderPositionTableModel(orderPositions);
        orderPaymentTableModel = new OrderPaymentTableModel(orderPayments);

        orderPositionsTable.setModel(orderPositionTableModel);
        orderPositionsTable.getColumn("Наименование").setMinWidth(310);
        paymentsTable.setModel(orderPaymentTableModel);
        checkPrePaymentPrintAvailability();

        orderPositionsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                int row = orderPositionsTable.getSelectedRow();
                if ((row >= 0) && (row < orderPositionsTable.getRowCount())) {
                    editViewButton.setEnabled(true);
                    deleteOrderPosition.setEnabled(true);

                } else {
                    editViewButton.setEnabled(false);
                    deleteOrderPosition.setEnabled(false);
                }
            }
        });
        paymentsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                int row = paymentsTable.getSelectedRow();
                if ((row >= 0) && (row < paymentsTable.getRowCount())) {
                    editPaymentButton.setEnabled(true);
                    deletePaymentButton.setEnabled(true);

                } else {
                    editPaymentButton.setEnabled(false);
                    deletePaymentButton.setEnabled(false);
                }
            }
        });

        calculateGeneralSum();
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addFromShopButton;
    private javax.swing.JButton addOrderPosition;
    private javax.swing.JButton addPaymentButton;
    private javax.swing.JButton cancelButton;
    private javax.swing.JButton deleteOrderPosition;
    private javax.swing.JButton deletePaymentButton;
    private javax.swing.JButton editPaymentButton;
    private javax.swing.JButton editViewButton;
    private javax.swing.JTextField generalSumField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JPanel moneyPanel;
    private org.jdesktop.swingx.JXDatePicker orderDatePicker;
    private javax.swing.JPanel orderDetailsPanel;
    private javax.swing.JPanel orderPositionsPanel;
    private org.jdesktop.swingx.JXTable orderPositionsTable;
    private javax.swing.JTextField ostTextField;
    private javax.swing.JPanel paymentsPanel;
    private org.jdesktop.swingx.JXTable paymentsTable;
    private javax.swing.JButton printPrePaymentsButton;
    private javax.swing.JButton printSchetButton;
    private javax.swing.JButton saveButton;
    private javax.swing.JComboBox statusComboBox;
    // End of variables declaration//GEN-END:variables

    protected OrderPosition getOrderPositionSelection() {
        if (orderPositionsTable.getSelectedRow() > -1) {
            OrderPosition orderPosition = (OrderPosition) orderPositionsTable
                    .getValueAt(orderPositionsTable.getSelectedRow(), -1);
            return orderPosition;
        }
        return null;
    }

    protected OrderPayment getOrderPaymentSelection() {
        if (paymentsTable.getSelectedRow() > -1) {
            OrderPayment orderPayment = (OrderPayment) paymentsTable
                    .getValueAt(paymentsTable.getSelectedRow(), -1);
            return orderPayment;
        }
        return null;
    }

    protected void calculateGeneralSum() {
        Double general = 0.0;
        if (null != orderPositions) {
            for (OrderPosition op : orderPositions) {
                general += (op.getPrice() * op.getAmount());
            }
        }
        generalSumField.setText(general.toString());

        Double payed = 0.0;
        if (null != orderPayments) {
            for (OrderPayment op : orderPayments) {
                payed += op.getSumma();
            }
        }
        Double ost = general - payed;
        ostTextField.setText(ost.toString());
    }

    public void setOrdersTableModel(OrdersTableModel ordersTableModel) {
        this.ordersTableModel = ordersTableModel;
    }

    private void checkPrePaymentPrintAvailability() {
        if (paymentsTable.getRowCount() > 0) {
            printPrePaymentsButton.setEnabled(true);
        } else {
            printPrePaymentsButton.setEnabled(false);
        }
    }

    public void setCar(Car car) {
        this.car = car;
    }

    public JuridicalPerson getJuridicalPerson() {
        return juridicalPerson;
    }

    public void setJuridicalPerson(JuridicalPerson juridicalPerson) {
        this.juridicalPerson = juridicalPerson;
    }
}
